package com.codeshellme.bookmanager.service.impl;

import com.codeshellme.bookmanager.dao.UmsMenuDao;
import com.codeshellme.bookmanager.dao.UmsRoleDao;
import com.codeshellme.bookmanager.dto.UmsRole;
import com.codeshellme.bookmanager.dto.UmsUser;
import com.codeshellme.bookmanager.service.UmsRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UmsRoleServiceImpl implements UmsRoleService {

    @Autowired
    private UmsMenuDao umsMenuDao;

    @Autowired
    private UmsRoleDao umsRoleDao;


    @Override
    public List<Map<String, Object>> queryAllRoles() {
        return umsRoleDao.queryAllRoles();
    }

    @Override
    public List<Map<String, Object>> queryMenuTreeByRoleId(Integer roleId) {
        // 目录菜单
        List<Map<String, Object>> dirMenus = umsMenuDao.queryMenus("DIR");
        // 子菜单
        List<Map<String, Object>> subMenus = umsMenuDao.queryMenus("SUBMENU");

        List<Map<String, Object>> retMenus = new ArrayList<>();

        for (Map<String, Object> dirMenu: dirMenus) {
            Map<String, Object> m = new HashMap<>();
            List<Map<String, Object>> children = new ArrayList<>();

            m.put("id", dirMenu.get("id"));
            m.put("text", dirMenu.get("name"));
            m.put("iconCls", dirMenu.get("icon"));
            m.put("children", children);
            String id = dirMenu.get("id").toString();

            // 父菜单中不用添加 checked 属性
//            Integer menuId = Integer.parseInt(id);
//            Map<String, Object> exist = umsRoleDao.existRoleAndMenu(roleId, menuId);
//            if (exist == null) m.put("checked", false);
//            else m.put("checked", true);

            for (Map<String, Object> subMenu: subMenus) {
                String parent_id = subMenu.get("parent_id").toString();
                if (!parent_id.equals(id)) {
                    continue;
                }

                Map<String, Object> mm = new HashMap<>();
                mm.put("id", subMenu.get("id"));
                mm.put("text", subMenu.get("name"));
                mm.put("iconCls", subMenu.get("icon"));
                mm.put("url", subMenu.get("url"));

                Integer menuId = Integer.parseInt(subMenu.get("id").toString());
                Map<String, Object> exist = umsRoleDao.existRoleAndMenu(roleId, menuId);
                if (exist == null) mm.put("checked", false);
                else mm.put("checked", true);

                children.add(mm);
            }

            retMenus.add(m);
        }

        return retMenus;
    }


    @Override
    @Transactional
    public int processRoleMenus(Integer roleId, Integer menuId, String menuType, Boolean checked) {
        // 该函数中的重复异常被认为是正常现象，可忽略

        if (menuType.equals("DIR")) {
            // 如果菜单类型是目录，则需要将目录下的所有子菜单都"插入/删除"

            // 子菜单
            List<Map<String, Object>> subMenus = umsMenuDao.querySubMenusById(menuId);

            // 第一步 处理所有的子菜单
            for (Map<String, Object> subMenu: subMenus) {
                Integer subMenuId = Integer.parseInt(subMenu.get("id").toString());
                if (checked) {
                    // 注意该操作，如果子菜单已在表中，则该语句会报重复
                    try {
                        umsRoleDao.addRoleMenu(roleId, subMenuId);
                    } catch (DuplicateKeyException e) {
                        // 不需要做处理
                    }
                } else {
                    // 注意该操作，如果子菜单已不在表中，则该语句不会影响任何数据
                    umsRoleDao.delRoleMenu(roleId, subMenuId);
                }
            }

            // 第二步 处理目录菜单
            if (checked) {
                try {
                    umsRoleDao.addRoleMenu(roleId, menuId);
                } catch (DuplicateKeyException e) {
                    // 不需要做处理
                }
            } else {
                umsRoleDao.delRoleMenu(roleId, menuId);
            }

        } else {
            // 如果菜单类型是子菜单，则只需要将该子菜单"插入/删除"即可

            String parent_id = umsMenuDao.queryMenuById(menuId, 1)
                    .get("parent_id").toString();       // menuId 的父菜单

            if (checked) {
                // 第一步 增加菜单
                umsRoleDao.addRoleMenu(roleId, menuId);

                // 第二步
                // 如果是第一个子菜单，则需要添加父菜单
                // 这里并没有判断是否是第一个子菜单，而是直接将父菜单插入
                // 如果父菜单已存在，则会报重复
                try {
                    umsRoleDao.addRoleMenu(roleId, Integer.parseInt(parent_id));
                } catch (DuplicateKeyException e) {
                    // 不需要做处理
                }

            } else {
                // 第一步 删除菜单
                umsRoleDao.delRoleMenu(roleId, menuId);

                // 第二步
                // 如果是最后一个子菜单，则需要删除父菜单
                List<Map<String, Object>> list = umsRoleDao.queryRolesByRoleIdMenuId(roleId, menuId);
                if (list.size() == 0) {
                    // 0 说明已没有兄弟菜单
                    // 是最后一个子菜单，删除父菜单
                    umsRoleDao.delRoleMenu(roleId, Integer.parseInt(parent_id));
                }
            }
        }

        return 1;
    }

    @Override
    public int addRole(UmsRole role) {
        return umsRoleDao.addRole(role);
    }

    @Override
    public int updateRole(UmsRole role) {
        return umsRoleDao.updateRole(role);
    }

    @Override
    @Transactional
    public int deleteRoleById(Integer roleId) {
        // 第一步 删除角色
        umsRoleDao.delRoleById(roleId);

        // 第二步 删除角色相关的菜单数据
        umsRoleDao.delRoleMenus(roleId);

        return 1;
    }

    @Override
    public Boolean verifyRoleSign(String roleSign) {
        Map<String, Object> role = umsRoleDao.findByRoleSign(roleSign);
        if (role == null) {
            return true;    // 没有找到角色，可用
        } else {
            return false;    // 找到了角色，不可用
        }
    }
}
